﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Collections;
//using Grishko.DataTier;
//using OutdoorLib.Context;
//using OutdoorLib.BaseEntity.WS;
//using OutdoorLib.BaseEntity.Agency;
//using Grishko.SerilizeTools;

//namespace OutdoorLib.BaseEntity.Dictionary
//{
//     <summary>
//     Базовый класс дя справочников имеющих иерархическую структуру 
//     Адресная программа,справочник типов рекламны поверхностей и т.д.
//     </summary>
//    public class TreeDictionaryItem : DictionaryItem
//    {

//        public override string ID
//        {
//            get
//            {
//                return base.ID;
//            }
//            set
//            {
//                base.ID = value;
//            }
//        }
//        [EntityNonSerialized]
//        public override TreeEntitySingle ParentNode
//        {
//            get
//            {
//                return base.ParentNode;
//            }
//            set
//            {
//                Дерево справочника - представлет коллекцию параметр - значения 
//                - где  ParamID= id узла Value= значению тек. элемента 
//                ParamID = (value == null ? string.Empty : ParamID = value.ID);
//                Value = ID;
//                base.ParentNode = value;
//            }
//        }


//        public TreeDictionaryItem() : base() { }
//        public TreeDictionaryItem(TreeEntitySingle Source)
//            : base()
//        {
//            foreach (TreeEntitySingle item in Source.ChildNodes) { this.ChildNodes.Add(item); }

//        }



//        private string _Name = string.Empty;
//         <summary>
//         Соответсвует Value DictionaryItem
//         </summary>
//        public string Name { get { return _Name; } set { _Name = value; } }

//         <summary>
//         категория древовидного справочника
//         </summary>
//        private string _TypeID = string.Empty;
//        public string TypeID { get { return _TypeID; } set { _TypeID = value; } }


//         <summary>
//         Сформирвать из дерва справочника коллекцию параметр значение, 
//         где key- ID ветки, Value - Name ветки
//         </summary>
//         <param name="Dictionatry"></param>
//         <returns></returns>
//        public Hashtable ToHashtable()
//        {
//            Func<TreeDictionaryItem, Hashtable, Hashtable> f = delegate(TreeDictionaryItem nd, Hashtable tbl)
//            {
//                tbl.Add(nd.ID, nd.Name);
//                return tbl;
//            };
//            Hashtable r = new Hashtable();
//            FindNextBranch(this, r, f);
//            return r;
//        }

//        private void FindNextBranch(TreeDictionaryItem nd, Hashtable tbl, Func<TreeDictionaryItem, Hashtable, Hashtable> f)
//        {
//            f(nd, tbl);
//            nd.ChildNodes.Reset();
//            foreach (TreeDictionaryItem item in nd.ChildNodes)
//            {
//                FindNextBranch(item, tbl, f);
//            }
//            nd.ChildNodes.Reset();

//        }


//        public HashSet<TreeDictionaryItem> ToHashSet()
//        {
//            Func<TreeDictionaryItem, HashSet<TreeDictionaryItem>, HashSet<TreeDictionaryItem>> ff = delegate(TreeDictionaryItem nd, HashSet<TreeDictionaryItem> tbl)
//            {
//                tbl.Add(nd);
//                return tbl;
//            };
//            HashSet<TreeDictionaryItem> t = new HashSet<TreeDictionaryItem>();
//            FindNextBranch_(this, t, ff);
//            return t;
//        }

//        private void FindNextBranch_(TreeDictionaryItem nd, HashSet<TreeDictionaryItem> tbl, Func<TreeDictionaryItem, HashSet<TreeDictionaryItem>, HashSet<TreeDictionaryItem>> ff)
//        {
//            ff(nd, tbl);
//            nd.ChildNodes.Reset();
//            foreach (TreeDictionaryItem item in nd.ChildNodes)
//            {
//                FindNextBranch_(item, tbl, ff);
//            }
//            nd.ChildNodes.Reset();
//        }

//         <summary>
//         УСТАРЕЛ Используется GetValueAsString
//         Преобразует значение параметра в текстовый вид  
//         </summary>
//         <param name="Dictionatry"></param>
//         <param name="Value"></param>
//         <param name="ParamSeparator"> разделитель между параметрами </param>
//         <param name="ItemSeparator"> разделитель между несколькими значениями одного параметра</param>
//         <returns></returns>
//        public  string ValueAsString(   TreeDictionaryItemValue Value,
//                                        string ParamSeparator,
//                                        string ItemSeparator)
//        {
//            if (null == this) return string.Empty;
//            if (null == Value) return string.Empty;

//            // сформировать табличку параметр -значение 
//            Hashtable ParamTbl = new Hashtable();
//            Value.ChildNodes.Reset();
//            foreach (DictionaryItem item in Value.ChildNodes)
//            {
//                // если параметр со множеством значений - просто значеня через запятую

//                if (ParamTbl[item.ParamID] != null)
//                {
//                    List<string> ListValue = (List<string>)ParamTbl[item.ParamID];
//                    ListValue.Add(item.Value.ToString());
//                    ParamTbl[item.ParamID] = ListValue;
//                }
//                else
//                {
//                    List<string> SingleListValue = new List<string>();
//                    SingleListValue.Add(item.Value.ToString());
//                    ParamTbl.Add(item.ParamID, SingleListValue);
//                }


//            }
//            // Сформировать справочник в виде хэш таблички 
//            Hashtable DictionatryTbl = this.ToHashtable();

//            // описать функцию сопоставления текущего элемента дервва и набора параметров из ParamTbl
//            Func<TreeDictionaryItem, Hashtable, Hashtable, StringBuilder, StringBuilder> f = delegate(TreeDictionaryItem _nd, Hashtable _ParamTbl, Hashtable _DictionatryTbl, StringBuilder Result)
//            {

//                // параметр не наш?
//                if (null == ParamTbl[_nd.ID]) return Result;

//                // ищем текстовое значение параметра                                
//                string txt = string.Empty;
//                List<string> sValue = (List<string>)ParamTbl[_nd.ID];
//                // если текст значения не найден - значение не справочное а вводимое.
//                foreach (string s in sValue)
//                {
//                    string value = (string)_DictionatryTbl[s];
//                    if (null == value)
//                        txt = txt + (txt == string.Empty ? string.Empty : ItemSeparator) + s;
//                    else
//                        txt = txt + (txt == string.Empty ? string.Empty : ItemSeparator) + value;

//                }

//                Result.Append(txt);
//                Result.Append(ParamSeparator);
//                return Result;

//            };

//            StringBuilder res = new StringBuilder();
//            FindNextDictionaryItem(this, ParamTbl, DictionatryTbl, f, res);
//            return res.ToString();

//        }

//        private void FindNextDictionaryItem(TreeDictionaryItem nd,
//                                                    Hashtable ParamTbl,
//                                                    Hashtable DictionatryTbl,
//                                                    Func<TreeDictionaryItem, Hashtable, Hashtable, StringBuilder, StringBuilder> f,
//                                                    StringBuilder Result)
//        {
//            f(nd, ParamTbl, DictionatryTbl, Result);
//            nd.ChildNodes.Reset();
//            if (nd.ChildNodes.Count > 0)
//                foreach (TreeDictionaryItem item in nd.ChildNodes)
//                {

//                    FindNextDictionaryItem(item, ParamTbl, DictionatryTbl, f, Result); ;
//                }
//        }

//         <summary>
//         Вернуть описание справочника (системный не системный - глубина) строчка из vTreeDictionaryType
//         </summary>
//         <param name="Dictionatry"></param>
//         <returns></returns>
//        public TreeDictionaryTypeList_Item Get_TreeDictionaryTypeList_Item()
//        {
//            wsDictionary ws = (wsDictionary)AgencyLib_GlobalConstants.CurrentAgency.WS_FactoryList[WS_FactoryList.wsKey_Dictionary];
//            TreeDictionaryTypeList l = ws.GetTreeDictionaryTypeList();
//            return (TreeDictionaryTypeList_Item)l[this.TypeID];
//        }

//        public string ValueAsString
//            (string SingleVal)
//        {
//             Сформировать справочник в виде хэш таблички 
//            Hashtable DictionatryTbl = ToHashtable();
//            return DictionatryTbl[SingleVal].ToString();
//        }



//         <summary>
//         строит пустое TreeDictionaryItemValue
//         </summary>
//         <returns></returns>

//        public TreeDictionaryItemValue BuildValue()
//        {
//             создаем структуру справочника 
//            TreeDictionaryItemValue r = new TreeDictionaryItemValue() { Name = this.Name, TreeDictionaryTypeID = this.TypeID, ID = this.ID };

//             Устанавливаем папку справочника
//            r.TreeDictionaryFolderID = TreeDictionaryContext.GetFolderId(this.TypeID);
//            return r;

//        }

//         <summary>
//         Построить хранилище значений справочника от текущего элемента
//         Строит цепочку параметр значение от текущего эемента к корню
//         </summary>
//         <param name="Dictionatry"></param>
//         <param name="NodeId">Id ноды от которой будут строиться справочники </param>
//         <returns></returns>
//        public TreeDictionaryItemValue BuildValue(string NodeId)
//        {
//             Находим листок
//            DictionaryItem Leaf = (DictionaryItem)this.Find(NodeId);
//            if (null == Leaf) return null;

//             создаем структуру справочника 
//            TreeDictionaryItemValue r = BuildValue();


//            Func<DictionaryItem, EntityList, EntityList> fBuilder = delegate(DictionaryItem Source, EntityList NdVal)
//            {
//                if (Source.ParentNode != null)
//                {
//                    if (Source.ParentNode.ID.IndexOf(AgencyLib_GlobalConstants.qProxyId) == -1)
//                    {
//                        NdVal.Add(new DictionaryItem() { Value = Source.ID, ParamID = Source.ParentNode.ID });
//                    }
//                }

//                return NdVal;
//            };


//            Func<string, bool> CallBack = delegate(string ID)
//            {
//                r.ID = ID;
//                return true;
//            };

//            FindNext(Leaf, r.ChildNodes, fBuilder, CallBack);

//            if (0 == r.ChildNodes.Count) return null;  // Значений нет ?                        

//            return r;
//        }



//        private void FindNext(DictionaryItem NdSource,
//                                      EntityList NdVal,
//                                       Func<DictionaryItem, EntityList, EntityList> fBuilder,
//                                       Func<string, bool> CallBack)
//        {
//            fBuilder(NdSource, NdVal);
//             выскакиваем если дошли до вершины или до прокси ноды
//            if (null == NdSource.ParentNode)
//            {
//                CallBack(NdSource.ID);
//                return;
//            }
//            if (null != NdSource.ParentNode)
//            {
//                if (NdSource.ParentNode.ID.IndexOf(AgencyLib_GlobalConstants.qProxyId) > -1)
//                {
//                    CallBack(NdSource.ID);
//                    return;
//                }


//                FindNext((DictionaryItem)NdSource.ParentNode, NdVal, fBuilder, CallBack);
//            }

//        }

//         <summary>
//         Сливает две ветки одного справочника в одну
//         Подливает значения со значениями Source значения имеющие одинаковую пару тип параметра значения игнорируются
//         ВНИМАНИЕ: Корректно работает только для выбранных значений   на одном уровне Починить!!!
//         </summary>
//         <param name="Dictionatry"></param>
//         <param name="Sorce"></param>
//        public void Merge(List<DictionaryItem> Source)
//        {
//            DictionaryItemComparer c = new DictionaryItemComparer();
//            List<DictionaryItem> result = this.ChildNodes.ToList<DictionaryItem>();
//            IEnumerable r = result.Union(Source, c);
//            EntityList rslt = new EntityList();
//            this.ChildNodes.Reset();

//            this.ChildNodes.Clear();
//            foreach (DictionaryItem item in r)
//            {
//                this.ChildNodes.Add(item);
//            }
//        }


//         <summary>
//         Суммирует два массива  справочников в отдно дерево - на выходе справочник с общим корнем. С двумя ветками
//         Массивы справочников - должны именть однотипные элементы
//         </summary>
//         <param name="BaseDictionary"></param>
//         <param name="AddDictionary"></param>
//         <returns></returns>
//        public TreeDictionaryItem AddArr(TreeDictionaryItem[] BaseDictionary, TreeDictionaryItem[] AddDictionary)
//        {
//             хоть один системный справочник заданного типа существует
//            TreeDictionaryItem first = BaseDictionary[0];
//            TreeDictionaryItem res = new TreeDictionaryItem() { TypeID = first.TypeID, Name = first.Name };
//            for (int i = 0; i < BaseDictionary.Length; i++)
//            {
//                BaseDictionary[i].ChildNodes.Reset();
//                foreach (TreeDictionaryItem item in BaseDictionary[i].ChildNodes)
//                {
//                    res.ChildNodes.Add(item);
//                }
//            }

//            return res;
//        }

//        public class DictionaryItemComparer : IEqualityComparer<DictionaryItem>
//        {

//            public DictionaryItemComparer()
//            {

//            }
//            #region IEqualityComparer<DictionaryItem> Members

//            public bool Equals(DictionaryItem x, DictionaryItem y)
//            {
//                return (x.ParamID == y.ParamID && y.Value == x.Value);
//            }

//            public int GetHashCode(DictionaryItem obj)
//            {
//                return obj.GetHashCode();
//            }

//            #endregion
//        }

//        public string GetValueAsString(TreeDictionaryItemValue v)
//        {
//            TreeDictionaryItem root = (TreeDictionaryItem)this.First;
//            StringBuilder sBuilder = new StringBuilder();

//            TreeDictionaryItemValue.Comparer cmp = new TreeDictionaryItemValue.Comparer();
//            HashSet<DictionaryItem> Values = v.ChildNodes.ToHashSet<DictionaryItem>(cmp);




//            string _RootNodeId = string.Empty;
//            Func<TreeDictionaryItem, StringBuilder> fBuild = delegate(TreeDictionaryItem nd)
//            {
//                if (null == nd)
//                    return sBuilder;

//                 Корень спрваочника не выводим
//                if (nd.ParentNode == null)
//                {
//                    _RootNodeId = nd.ID;
//                    return sBuilder;
//                }

//                if (nd.ParentNode.ID == AgencyLib_GlobalConstants.qProxyId)
//                {
//                    _RootNodeId = nd.ID;
//                    return sBuilder;
//                }
//                ///////////////////////////////////////////////////////////////////////

//                string term = (_RootNodeId == nd.ParentNode.ID ? "|" : " ");
//                if (Values.Contains(nd as DictionaryItem))
//                    sBuilder.Append((sBuilder.Length > 0 ? term : " ") + nd.Name);


//                return sBuilder;
//            };


//            NextBranch_(root, fBuild);
//            return sBuilder.ToString();
//        }

//        private void NextBranch_(TreeDictionaryItem nd, Func<TreeDictionaryItem, StringBuilder> fBuild)
//        {
//            fBuild(nd);
//            nd.ChildNodes.Reset();
//            foreach (TreeDictionaryItem i in nd.ChildNodes)
//            {
//                NextBranch_(i, fBuild);
//            }

//        }

//        public static TreeDictionaryItem GetTreeDictionary(string FolderId, string DictionaryID)
//        {
//            wsDictionary _ws_Dictionary = new wsDictionary();
//            return (TreeDictionaryItem)_ws_Dictionary.GetTreeDictionary(FolderId, DictionaryID);

//        }
//    }

//}